<?php


namespace app\admin\model;


use app\common\lib\RedisKey;
use app\common\lib\RespCode;
use app\common\model\BaseModel;
use custom\Err;
use custom\Log;
use custom\Redis;
use custom\Token;
use think\Db;
use think\Exception;

class Admin extends BaseModel {

    // 隐藏状态
    const STATUS_NO = 0;
    // 正常状态
    const STATUS_YES = 1;
    // 状态集合
    const STATUS_ARR = [
        self::STATUS_NO,
        self::STATUS_YES
    ];

    /**
     * 列表
     * @param $params
     * @return array
     */
    public function getList($params) {
        // 用户名|昵称
        $where = [];
        $where[] = ['a.id', '<>', config('global.admin_id')];
        if (!empty($params['account'])) {
            $where[] = ['a.account|a.nickname', 'like', "%{$params['account']}%"];
        }
        // 组别
        if (!empty($params['role_id'])) {
            $where[] = ['a.role_id', '=', $params['role_id']];
        }
        $count = db('admin')
            ->alias('a')
            ->join('erp_admin_role ar', 'a.role_id=ar.id', 'LEFT')
            ->where($where)
            ->count();
        if ($count == 0) {
            $count = 0;
            $pageNum = 1;
            $data = [];
        } else {
            $pageNum = ceil($count / $params['row']);
            $data = db('admin')
                ->alias('a')
                ->join('erp_admin_role ar', 'a.role_id=ar.id', 'LEFT')
                ->where($where)
                ->field('a.id,a.account,a.nickname,a.log_time,ar.name as role_name,a.status')
                ->page($params['page'], $params['row'])
                ->select();
            foreach ($data as $k => $v) {
                if (!empty($data[$k]['log_time'])) {
                    $data[$k]['log_time'] = date('Y-m-d H:i:s', $data[$k]['log_time']);
                } else {
                    $data[$k]['log_time'] = '未登陆';
                }
            }
        }
        return [$count, $pageNum, $data];
    }

    /**
     * 用户详情
     * @param $id
     * @return array|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function info($id) {
        return db('admin')->where('id', $id)->field('pwd', true)->find();
    }

    /**
     * 添加
     * @param $params
     * @return bool|int|string
     */
    public function add($params) {
        if (!$this->verifyParams($params)) {
            return false;
        }
        if ($params['role_id'] == 1) {
            if (db('admin')->where('role_id', $params['role_id'])->count() >= 1) {
                Err::add('只能添加一个超级管理员', RespCode::PARAMS_ERR);
                return false;
            }
        }
        return db('admin')->strict(false)->insertGetId($params);
    }

    /**
     * 修改
     * @param $params
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function edit($params) {
        if (!$this->verifyParams($params)) {
            return false;
        }

        if (!db('admin')->where('id', $params['id'])->find()) {
            Err::add('数据不存在');
            return false;
        }

        return db('admin')->where('id', $params['id'])->strict(false)->update($params);
    }

    /**
     * 删除
     * @param $id
     * @return int
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function del($id) {
        return db('admin')->where('id', $id)->delete();
    }

    /**
     * 获取登录详情
     * @param $id
     * @param $field
     * @return mixed
     */
    public static function getInfo($id, $field = "*") {
        $field = 'a.id,a.account,a.nickname,a.role_id,a.status,ar.level,a.account';
        $info = Db::name('admin')
            ->alias('a')
            ->join('erp_admin_role ar', 'a.role_id = ar.id', 'LEFT')
            ->field($field)
            ->where('a.id', $id)
            ->find();
        // 权限拆分
        $info['level'] = $info['level'] == "*" ? "*" : AdminRole::levelSplitNum(json_decode($info['level'], true));
        return $info;
    }

    /**
     * 参数验证
     * @param $params
     * @return bool
     */
    protected function verifyParams(&$params) {
        // 组别
        if (db('admin_role')->where('id', $params['role_id'])->count() == 0) {
            Err::add('不存在的组别', RespCode::PARAMS_ERR);
            return false;
        }
        // 用户名
        if (!preg_match("/^[a-zA-Z0-9_]{1,20}$/", $params['account'])) {
            Err::add('用户名：20长度，数字、字母、下划线', RespCode::PARAMS_ERR);
            return false;
        }
        // 昵称
        if (!preg_match("/^([\x{4e00}-\x{9fa5}]|\w){1,10}$/u", $params['nickname'])) {
            Err::add('昵称：10长度，数字、字母、汉字、下划线', RespCode::PARAMS_ERR);
            return false;
        }
        // 密码
        if (empty($params['id'])) {//添加
            if (!preg_match("/^[a-zA-Z0-9]{6,15}$/", $params['pwd'])) {
                Err::add('密码：6-15位字母或数字', RespCode::PARAMS_ERR);
                return false;
            }
            $params['pwd'] = md5(md5($params['pwd']));
        }
        // 状态
        if (!in_array($params['status'], self::STATUS_ARR)) {
            Err::add('状态错误', RespCode::PARAMS_ERR);
            return false;
        }

        // 用户名重复验证
        $where[] = ['account', '=', $params['account']];
        if (!empty($params['id'])) {
            $where[] = ['id', '<>', $params['id']];
        }
        if (db('admin')->where($where)->count() > 0) {
            Err::add('用户名已存在', RespCode::PARAMS_ERR);
            return false;
        }
        if (!empty($params['id']) && $params['id'] == 1) {//编辑
            Err::add('禁止编辑系统超级管理员', RespCode::PARAMS_ERR);
            return false;
        }
        $params['utime'] = time();
        return true;
    }

    /**
     * 校验登陆
     * @param $params
     * @return array|bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function checkLogin($params) {
        $admin = \db('admin')
            ->alias('a')
            ->join('admin_role ar', 'ar.id = a.role_id')
            ->where('a.account', $params['account'])
            ->field('a.id,a.pwd,ar.level,a.nickname,ar.name,a.status,a.account')
            ->find();
        if (empty($admin)) {
            Err::add('账号密码错误', RespCode::QUERY_ERR);
            return false;
        }
        if ($admin['pwd'] != md5(md5($params['pwd']))) {
            Err::add('账号密码错误', RespCode::QUERY_ERR);
            return false;
        }
        if ($admin['status'] == 0) {
            Err::add('账号已被禁用', RespCode::QUERY_ERR);
            return false;
        }
        $token = new Token();
        $token_string = $token->getToken($admin['id'], [], Token::ADMIN_TOKEN, Token::EXPIRE_TIME, RedisKey::ADMIN_TOKEN_HASH);
        //更新最近登录时间
        self::where('id', $admin['id'])->update(['log_time' => time()]);
        $data = ['token' => $token_string];

        $saveLog = [
            'admin_name' => (string)$admin['account'],
            'title'      => '登录',
            'ip'         => (string)request()->ip(),
            'itime'      => (string)time(),
        ];
        try{
            if(!LoginLog::saveLoginLog($saveLog)){
                throw new Exception('登录日志写入失败');
            }
        }catch (Exception $e){
            $err = "异常信息:{$e->getMessage()} | 异常所在的代码行:{$e->getLine()} | 异常文件{$e->getFile()} | php 版本 " . PHP_VERSION . "(" . PHP_OS . ")";
            Log::write($err, "saveLoginLog.log");
        }

        return $data;
    }

    /**
     * 修改个人信息
     * @param $params
     * @return bool
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function editMyself($params) {
        $model = new self();
        $data = $model->getByid($params['user_id'])->toArray();
        //验证原始密码
        if ($data['pwd'] != md5(md5($params['old_pwd']))) {
            Err::add('原始密码错误', RespCode::PARAMS_ERR);
            return false;
        }
        if ($params['pwd'] != $params['again_pwd']) {
            Err::add('两次密码输入不一致', RespCode::PARAMS_ERR);
            return false;
        }
        if (!preg_match("/^[a-zA-Z0-9]{6,15}$/", $params['pwd'])) {
            Err::add('密码：6-15位字母或数字', RespCode::PARAMS_ERR);
            return false;
        }
        $update = [
            'pwd' => md5(md5($params['pwd']))
        ];
        if (!$model->where('id', $params['user_id'])->update($update)) {
            Err::add('新密码不能等于原始密码', RespCode::PARAMS_ERR);
            return false;
        }
        $redisModel = Redis::getInstance();
        $redisModel->hdel(RedisKey::ADMIN_TOKEN_HASH . '_' . Token::ADMIN_TOKEN, $data['id']);
        return true;
    }

    public static function quit($headers, $uInfo) {
        $saveLog = [
            'admin_name' => (string)$uInfo['account'],
            'title'      => '退出',
            'ip'         => (string)request()->ip(),
            'itime'      => (string)time(),
        ];
        try{
            if(!LoginLog::saveLoginLog($saveLog)){
                throw new Exception('退出日志写入失败');
            }
        }catch (Exception $e){
            $err = "异常信息:{$e->getMessage()} | 异常所在的代码行:{$e->getLine()} | 异常文件{$e->getFile()} | php 版本 " . PHP_VERSION . "(" . PHP_OS . ")";
            Log::write($err, "saveLoginLog.log");
        }
        $str = substr(base64_decode(substr($headers['token'], 32), true), 32);
        $redisKey = RedisKey::ADMIN_TOKEN_HASH . '_' . Token::ADMIN_TOKEN;
        $redisModel = Redis::getInstance();
        if (!$redisModel->hDel($redisKey, $str)) {
            Err::add('请稍后重试', RespCode::PARAMS_ERR);
            return false;
        }
        return true;
    }


}